﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Net;
using System.Net.Sockets;
using MyLibrary;
using MyLibrary.Task;

namespace MyLibrary.Net.TCP
{
    /// <summary>
    /// 客户端和服务段之间的会话类
    /// </summary>
    public class TCPSession : DisposeableBase
    {
        internal event EventHandler<DataBlockArgs> OnReceiveData;
        Socket _socket;
        DataBlock _buffer;
        int _id;
        internal IAsyncResult _recvResult;
        internal IAsyncResult _sendResult;

        public int ID
        {
            get { return _id; }
        }

        /// <summary>
        /// 会话使用的Socket
        /// </summary>
        public Socket SessionSocket
        {
            get { return _socket; }
            set 
            {
                _socket = value;
                if (value != null)
                    _id = value.Handle.ToInt32();
            }
        }

        /// <summary>
        /// 数据块
        /// </summary>
        public DataBlock Buffer
        {
            get { return _buffer; }
            set { _buffer = value; }
        }

        TimeCounter timer = new TimeCounter();
        /// <summary>
        /// 活动计时器
        /// </summary>
        public TimeCounter TimeCounter
        {
            get { return timer; }
        }

        public TCPSession()
        {
            OnCreate();
        }

        protected virtual void OnCreate()
        {
            Buffer = new DataBlock(4096);
        }
        /// <summary>
        /// 检查会话是否还处于活动状态
        /// </summary>
        /// <param name="timeOut">超时时间(ms)</param>
        /// <returns>正在活动返回true 否则返回false</returns>
        public virtual bool IsActive(int timeOut)
        {
            NetDebuger.PrintDebugMessage(this, String.Format("TimeOut:{0}-Period:{1}", timeOut, TimeCounter.Milliseconds));
            if (timeOut < TimeCounter.Milliseconds)
                return false;
            else
                return true;
        }

        /// <summary>
        /// 接收readCount个数据
        /// </summary>
        /// <param name="readCount">读取数据个数</param>
        internal protected virtual void ReceivedData(int readCount)
        {
            Buffer.WriteIndex += readCount;
            if (this.OnReceiveData != null)
                this.OnReceiveData(this, new DataBlockArgs(Buffer));
        }

        /// <summary>
        /// 关闭会话
        /// </summary>
        public virtual void Close()
        {
            try
            {
                if (SessionSocket != null && !Disposed)
                {
                    lock (SessionSocket)
                    {
                        if (SessionSocket != null && !Disposed)
                        {
                            if (SessionSocket.Connected)
                                SessionSocket.Shutdown(SocketShutdown.Both);
                            SessionSocket.Close();
                            SessionSocket = null;
                        }
                    }
                }
            }
            catch (NullReferenceException) { }
            catch (ObjectDisposedException) { }
            catch (NetException) { }
        }

        protected override void Free(bool disposedByUser)
        {
            if (disposedByUser)
                Close();
            base.Free(disposedByUser);
        }

        public override string ToString()
        {
            return String.Format("TCP-S:{0:0000}", ID);
        }
    }
}
